﻿using System;
using System.Web.Security;
using MugenInjection.Bindings.Builders;
using MugenInjection.Infrastructure;
using MugenInjection.Interface;
using MugenInjection.Syntax;
using MugenInjection.Web.Config;
using MugenInjection.Web.Interface;
using MugenInjection.Web.Mvc.Config;
using System.Linq;

// ReSharper disable CheckNamespace

namespace MugenInjection
// ReSharper restore CheckNamespace
{
    /// <summary>
    /// Fluent api for MVC configuration.
    /// </summary>
    public static class MvcConfigExtension
    {
        #region Const

        /// <summary>
        /// Gets the key of Role-provider binding.
        /// </summary>
        public const string RoleProviderSetting = "RoleProviderSetting";

        /// <summary>
        /// Gets the key of Membership-provider binding.
        /// </summary>
        public const string MembershipProviderSetting = "MembershipProviderSetting";

        #endregion

        #region App extension

        /// <summary>
        /// Configures specified <see cref="IApplicationConfiguration"/> with MVC settings.
        /// </summary>
        /// <param name="configuration">The specified <see cref="IApplicationConfiguration"/></param>
        /// <returns></returns>
        public static T WithMvcConfiguration<T>(this T configuration) where T : IApplicationConfiguration
        {
            if (!configuration.Configurations.Any(configuration1 => configuration1 is MugenInjectionHttpApplicationConfig))
                configuration.WithHttpConfiguration();
            configuration.AddConfiguration(new MugenInjectionMvcApplicationConfig());
            return configuration;
        }

        /// <summary>
        /// Indicates that the application should be use the specified <see cref="RoleProvider"/>.
        /// </summary>
        public static T WithCustomRoleProvider<T>(this T configuration,
                                                  Func<IGenericBindingSyntax<RoleProvider>, IBindingBuilder>
                                                      roleProviderSyntax)
            where T : IApplicationConfiguration
        {
            Validate.ArgumentNotNull(roleProviderSyntax, "roleProviderSyntax");
            configuration.Injector.Unbind<RoleProvider>(RoleProviderSetting);
            IBindingBuilder providerSyntax =
                roleProviderSyntax(configuration.Injector.BindWithManualBuild<RoleProvider>());
            providerSyntax.Settings[BindingBuilderConfigurator.KeyedBindingKey] = RoleProviderSetting;
            providerSyntax.Build();
            return configuration;
        }

        /// <summary>
        /// Indicates that the application should be use the specified <see cref="MembershipProvider"/>.
        /// </summary>
        public static T WithCustomMembershipProvider<T>(this T configuration,
                                                        Func<IGenericBindingSyntax<MembershipProvider>, IBindingBuilder>
                                                            membershipSyntax)
            where T : IApplicationConfiguration
        {
            Validate.ArgumentNotNull(membershipSyntax, "membershipSyntax");
            configuration.Injector.Unbind<MembershipProvider>(MembershipProviderSetting);
            IBindingBuilder providerSyntax =
                membershipSyntax(configuration.Injector.BindWithManualBuild<MembershipProvider>());
            providerSyntax.Settings[BindingBuilderConfigurator.KeyedBindingKey] = MembershipProviderSetting;
            providerSyntax.Build();
            return configuration;
        }

        #endregion
    }
}